package com.suanfa.jiaoheng;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 使用knn算法实现一个数字识别
 * 资源是90*90的一个图片
 *
 * -16777216 image.getRGB的这个返回值好像标识黑色
 */
public class 第10课KNN算法 {
    final static Integer BLACK_VALUE =  -16777216;
    public static void main(String[] args) {
        Map<String,List<Position>> imageDataMap = 创建标准数();
        List<Position> testData = 读取图片("resources/jiaoheng/knn/test/4.1.png");
        knn算法(imageDataMap,testData);

    }


    static Map<String,List<Position>> 创建标准数(){
        Map<String,List<Position>> imageDataMap = new HashMap<>();
        Map<String,String> pathMap = new HashMap<>();
        pathMap.put("1","resources/jiaoheng/knn/train/1.png");
        pathMap.put("2","resources/jiaoheng/knn/train/2.png");
        pathMap.put("3","resources/jiaoheng/knn/train/3.png");
        pathMap.put("4","resources/jiaoheng/knn/train/4.png");
        for (Map.Entry<String,String> pathEntry : pathMap.entrySet()) {
            List<Position> positionList = 读取图片(pathEntry.getValue());
            imageDataMap.put(pathEntry.getKey(),positionList);
        }
        return imageDataMap;
    }

    /**
     * 读取图片，黑色位置数据的位置记录下来
     * @param path
     * @return
     */
    static List<Position> 读取图片(String path){
        List<Position> positions = new ArrayList<>();
        try {
            File file = new File(path);
            BufferedImage image = ImageIO.read(file);
            int width = image.getWidth();
            int height = image.getHeight();
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    int pixel = image.getRGB(j, i);
                    if(BLACK_VALUE.equals(pixel)){
                        positions.add(new Position(i,j));
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return positions;
    }

    static void knn算法(Map<String,List<Position>> imageDataMap,List<Position> testData){
        String matchValue = "";
        Double nearestValue = Double.MAX_VALUE;
        for (Map.Entry<String, List<Position>> dataEntry : imageDataMap.entrySet()) {
            Double totalDistance = 0.d;
            for (Position position : dataEntry.getValue()) {
                for (Position testDatePosition : testData) {
                    double distanceSquare = Math.abs(position.x-testDatePosition.x) * Math.abs(position.y-testDatePosition.y);
                    double distance = Math.sqrt(distanceSquare);
                    totalDistance+=distance;
                }
            }
            if(nearestValue>totalDistance){
                nearestValue = totalDistance;
                matchValue = dataEntry.getKey();
            }
        }
        System.out.println("识别出的数字是:"+matchValue);
    }


    static class Position{
        int x;
        int y;

        public Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }


}
